package stardust.core.network.protocol.http;


import java.util.ArrayList;
import java.util.List;


/**
 * Range
 * <p>
 * 请求实体的一个或者多个子范围。例如： <br>
 * 前500字节：bytes=0-499：new Range(0, 499) <br>
 * 从500字节到999字节：bytes=500-999：new Range(500, 999); <br>
 * 最后500字节：bytes=-500：new Range(null, 500); <br>
 * 表示500字节以后的范围：bytes=500-：new Range(500, null); <br>
 * 第一个和最后一个字节：bytes=0-0,-1：new Range(0, 0).add(null, 1); <br>
 * 同时指定几个范围：bytes=500-600,601-999：new Range(500, 600).add(601, 999); <br>
 * 但是服务器可以忽略此请求头，如果无条件GET包含Range请求头，响应会以状态码206（PartialContent）返回而不是以200（OK）。
 * <p/>
 * @author 陈昶
 */
public class Range
{

  /**
   * 字节区间实体列表
   */
  private List<RangeEntity> ranges;

  /**
   * 初始化
   */
  public Range()
  {
    this.ranges = new ArrayList<RangeEntity>();
  }

  /**
   * 前500字节：bytes=0-499：new Range(0, 499) <br>
   * 从500字节到999字节：bytes=500-999：new Range(500, 999); <br>
   * 最后500字节：bytes=-500：new Range(null, 500); <br>
   * 表示500字节以后的范围：bytes=500-：new Range(500, null); <br>
   * 第一个和最后一个字节：bytes=0-0,-1：new Range(0, 0).add(null, 1); <br>
   * 同时指定几个范围：bytes=500-600,601-999：new Range(500, 600).add(601, 999);
   */
  public Range(String range)
  {
    String[] rangs = range.split(",");
    String[] r;

    for (int i = 0; i < rangs.length; i++)
    {
      r = rangs[i].split("-");

      this.add((r[0].equals("") ? null : Long.parseLong(r[0])), (r[1].equals("") ? null : Long.parseLong(r[1])));
    }
  }

  /**
   * 初始化字节区间
   * <p/>
   * @param beginIndex
param endIndex
   */
  public Range(Long beginIndex, Long endIndex)
  {
    this();
    this.add(beginIndex, endIndex);
  }

  /**
   * 附加字节区间
   * <p>
   * 追加一段字节区间。
   * <p/>
   * @param beginIndex
param
   *                                                                       endIndex
   * <p/>
   * @return
   */
  public Range add(Long beginIndex, Long endIndex)
  {
    this.ranges.add(new RangeEntity(beginIndex, endIndex));

    return this;
  }

  /**
   * 获取字节区间表达式
   * <p/>
   * @return
   */
  public String getRange()
  {
    StringBuffer buffer = new StringBuffer();
    String rangeString;
    RangeEntity entity;

    for (int i = 0; i < this.ranges.size(); i++)
    {
      entity = this.ranges.get(i);
      rangeString = entity.getRange();

      if (rangeString != null)
      {
        buffer.append(rangeString);

        if (i < this.ranges.size() - 1)
        {
          buffer.append(", ");
        }
      }
    }

    return buffer.toString();
  }

  /**
   * toString
   */
  public String toString()
  {
    return this.getRange();
  }

  /**
   * 字符区间实体
   * <p/>
   * @author 陈昶
   */
  private class RangeEntity
  {

    /**
     * 开始字节索引
     */
    private Long beginIndex;

    /**
     * 结束字节索引
     */
    private Long endIndex;

    /**
     * 初始化字节区间
     * <p/>
     * @param beginIndex
param endIndex
     */
    public RangeEntity(Long beginIndex, Long endIndex)
    {
      if (beginIndex == null && endIndex == null)
      {
        throw new IllegalArgumentException("无效的字节区间表示。");
      }

      this.beginIndex = beginIndex;
      this.endIndex = endIndex;
    }

    /**
     * 获取字节区间表达式
     * <p/>
     * @return 当遇到异常的参数返回 null
     */
    public String getRange()
    {
      if (this.beginIndex == null && this.endIndex != null)
      {
        return "-" + Math.abs(this.endIndex);
      }
      else if (this.beginIndex != null && this.endIndex == null)
      {
        return Math.abs(this.beginIndex) + "-";
      }
      else if (this.beginIndex != null && this.endIndex != null)
      {
        return Math.abs(this.beginIndex) + "-" + Math.abs(this.endIndex);
      }
      else
      {
        return null;
      }
    }

  }

}
